package com.liang.aspect;

import com.liang.mall.entity.Admin;
import com.liang.mall.entity.Log;
import com.liang.service.LogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * Created with IntelliJ IDEA.
 * User: XIAOLIANG
 * Date: 2021/5/10
 * Time: 21:07
 * Description: No Description
 */
@Aspect
@Component
public class WebLogAspect {

    @Autowired
    LogService logService;

    private final static Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

    long startTime = 0;

    Log log = new Log();

    /** 以 controller 包下定义的所有请求为切入点 排除日志的操作 对日志本身的操作不再入库 */
//    @Pointcut("execution(public * com.liang.controller..*.*(..))  && !execution(* com.liang.controller.LogController.*(..))")
    @Pointcut("@annotation(com.liang.mall.myAnnotation.LogMethodInfo)")
    public void webLog() {}

    /**
     * 在切点之前织入
     * @param joinPoint
     * @throws Throwable
     */
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 开始打印请求日志
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        Admin admin = (Admin) request.getSession().getAttribute("admin");

        String username = "";

        String URL =  request.getRequestURL().toString();

        String IP = request.getRemoteAddr().equals("0:0:0:0:0:0:0:1")?"127.0.0.1":request.getRemoteAddr();
        String Method = joinPoint.getSignature().getName();

//        String Arges = new Gson().toJson(joinPoint.getArgs());

        String Arges = "";

        Object[] args = joinPoint.getArgs();
//        if (args != null) {
//            Arges = args[0].toString();
//        }

        if (admin!=null){
            username = admin.getUsername();
        }


        // 打印请求相关参数
        logger.info("========================================== Start ==========================================");
        // 打印请求 url
        logger.info("URL            : {}",URL);
        // 打印 Http method
        logger.info("HTTP Method    : {}", request.getMethod());
        // 打印调用 controller 的全路径以及执行方法
        logger.info("Class Method   : {}.{}", joinPoint.getSignature().getDeclaringTypeName(),Method);
        // 打印请求的 IP
        logger.info("IP             : {}", IP);
        // 打印请求入参
        logger.info("Request Args   : {}", Arges);
        logger.info("username:      : {}",username);


        log.setUsername(username);
        log.setIp(IP);
        log.setMethod(Method);
        log.setParams("Arges");

        startTime = System.currentTimeMillis();


    }

    /**
     * 在切点之后织入
     * @throws Throwable
     */
    @After("webLog()")
    public void doAfter() throws Throwable {


//        log.setUsername()
//        logService.save()
        long times = System.currentTimeMillis() - startTime;
        log.setTime(times);
        logService.save(log);
        logger.info("Time-Consuming : {} ms", times);
        logger.info("=========================================== End ===========================================");
        // 每个请求之间空一行
        logger.info("");
    }

//    /**
//     * 环绕
//     * @param proceedingJoinPoint
//     * @return
//     * @throws Throwable
//     */
//    @Around("webLog()")
//    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//        long startTime = System.currentTimeMillis();
//        Object result = proceedingJoinPoint.proceed();
//        // 打印出参
//        logger.info("Response Args  : {}", new Gson().toJson(result));
//        // 执行耗时
//        logger.info("Time-Consuming : {} ms", System.currentTimeMillis() - startTime);
//        return result;
//    }

}
